﻿/*
// operator new与operator delete函数
# include<iostream>
using namespace std;

class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		cout << "ListNode()" << endl;
	}

	~A()
	{
		cout << "~ListNode" << endl;
	}
private:
	int _a;
};

int main()
{
	A* p1 = (A*)malloc(sizeof(A));

	// operator new 的用法和malloc完全一样
	A* p2 = (A*)operator new(sizeof(A));

	// operator new和 malloc的不同在于：申请空间失败后的处理方式

	void* p3 = malloc(INT_MAX * 2);
	// 我们知道malloc是有可能申请空间失败的，失败会返回空指针，也就是0
	// 失败要不就是开着开着空间不够开了，要不就是一上来开的太大不够开了
	if (p3 == NULL)
	{
		// 之前我们学习过要这样处理
		perror("malloc()");// malloc(): Not enough space
	}

	// 而operator new 在申请失败后，会抛异常
	// 这里了解一下，后面会学习抛异常
	// 这里是失败抛异常——是面向对象处理错误的方式
	try
	{
		void* p4 = operator new(INT_MAX * 2);
		cout << p4 << endl;
	}
	catch (exception& e)
	{
		cout << e.what() << endl;// bad allocation
	}

	free(p1);
	operator delete(p2); // 释放空间失败不会抛异常
	// p3 p4 都申请失败了 不用释放了

	return 0;
}
*/

///*
//operator new：该函数实际通过malloc来申请空间，当malloc申请空间成功时直接返回；申请空间
//失败，尝试执行空间不足应对措施，如果改应对措施用户设置了，则继续申请，否则抛异常。
//*/
//# include <iostream>
//void* __CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
//{
//	// try to allocate size bytes
//	void* p;
//	while ((p = malloc(size)) == 0)
//		if (_callnewh(size) == 0)
//		{
//			// report no memory
//			// 如果申请内存失败了，这里会抛出bad_alloc 类型异常
//			static const std::bad_alloc nomem;
//			_RAISE(nomem);
//		}
//	return (p);
//}
//
///*
//operator delete: 该函数最终是通过free来释放空间的
//*/
//void operator delete(void* pUserData)
//{
//	_CrtMemBlockHeader* pHead;
//	RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
//	if (pUserData == NULL)
//		return;
//	_mlock(_HEAP_LOCK); /* block other threads */
//	__TRY;      /* get a pointer to memory block header */
//	pHead = pHdr(pUserData);
//		/* verify block type */
//	_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
//	_free_dbg(pUserData, pHead->nBlockUse);
//	__FINALLY
//		_munlock(_HEAP_LOCK); /* release other threads */
//	__END_TRY_FINALLY
//		return;
//}
///*
//free的实现
//*/
//#define   free(p)               _free_dbg(p, _NORMAL_BLOCK)


/*
// 定new表达式
 //使用格式：
 //new (place_address) type或者 new (place_address) type(initializer - list)
# include<iostream>
using namespace std;

class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		cout << "ListNode()" << endl;
	}

	~A()
	{
		cout << "~ListNode" << endl;
	}
private:
	int _a;
};

int main()
{
	// 我们想要开辟一个空间来存储A类的对象
	A* p1 = new A; // 我们会通过new来实现空间的开辟 + 调用构造函数
	delete p1;

	// 但是有时候，我们拿到了一个类的对象，但是它没有被初始化，这个时候我们就需要定new表达式
	// 因为我们需要去显式的调用构造函数，而构造函数往往是这个对象在定义的时候默认调用的
	A* p2 = (A*)operator new(sizeof(A));
	// 我们拿到了一个p2对象，但是它没有被初始化，也就是没有调用构造函数
	new(p2)A; // 调用p2所属类的构造函数
	// new (place_address) type == new(需要调用构造函数的对象)对象所属类名
	
	// 还可以传参，让其初始化成我们想给的值
	new(p2)A(10); // 调用其构造函数并传参
	// new (place_address) type(initializer - list)

	return 0;
}
*/
